﻿namespace CoreModule
{
    /// <summary>
    /// 血糖蓝牙测量信息
    /// </summary>
    public class BloodGlucoseMeasurementInfo
    {
        public BloodGlucoseMeasurementInfo()
        {
            
        } 
        /// <summary>
        /// 
        /// </summary>
        public bool IsValid { get; set; } = true;


        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        private static bool IsTrue(byte data, int index)
        {
            byte x = 1;
            switch (index)
            {
                case 0: { x = 0x01; } break;
                case 1: { x = 0x02; } break;
                case 2: { x = 0x04; } break;
                case 3: { x = 0x08; } break;
                case 4: { x = 0x10; } break;
                case 5: { x = 0x20; } break;
                case 6: { x = 0x40; } break;
                case 7: { x = 0x80; } break;
                default: { return false; }
            }
            return (data & x) == x ? true : false;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="first"></param>
        /// <param name="second"></param>
        /// <returns></returns>
        private static int CombineYear(byte first,byte second)
        {
            return second * 256 + first;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="first"></param>
        /// <param name="second"></param>
        /// <returns></returns>
        private static int CombineGlucoseConcentration(byte first, byte second)
        {
            return (second - 0xc0) * 256 + first;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static BloodGlucoseMeasurementInfo Create(byte[] bytes)
        {
            if (bytes.Length < 13)
            {
                return new BloodGlucoseMeasurementInfo()
                {
                    IsValid = false
                };
            }
              
        
            var byteIndex = 0;

            var info = new BloodGlucoseMeasurementInfo();
            var flags = bytes[byteIndex++];

            info.TimeOffsetPresent = IsTrue(flags, 0);
            info.LocationPresent = IsTrue(flags, 1);
            info.SensorStatusAnnunciationPresent = IsTrue(flags, 3);
            info.ContextInformationFollows = IsTrue(flags, 4);
             var flags5 = IsTrue(flags,5);
            var flags6 = IsTrue(flags, 6);
          
            if (flags5 && flags6)
            {
                info.MeasurementKind = MeasurementKind.总胆固醇;
            }
            else if ( flags6)
            {
                info.MeasurementKind = MeasurementKind.血红蛋白;
            }
            else if (flags5)
            {
                info.MeasurementKind = MeasurementKind.尿酸;
            }
            else
            {
                info.MeasurementKind = MeasurementKind.血糖;
            }

            ///当前忽略

            info.SeqNo = Extension.GetSeqNo(bytes[byteIndex++] , bytes[byteIndex++]);
             
            var year = CombineYear(bytes[byteIndex++], bytes[byteIndex++]);

            var month = bytes[byteIndex++];
            var day = bytes[byteIndex++];
            var hour = bytes[byteIndex++];
            var min = bytes[byteIndex++];
            var sec = bytes[byteIndex++];

            info.MeasurementTime = new DateTime(year, month, day, hour, min, sec);

            var value= CombineGlucoseConcentration(bytes[byteIndex++], bytes[byteIndex++]);
            switch (info.MeasurementKind)
            {
                case MeasurementKind.血糖:
                    info.MeasurementValue = value * 0.1f;
                    info.MeasurementValueString = info.MeasurementValue.ToString("F1");
                    break;
                case MeasurementKind.尿酸:
                    info.MeasurementValue = value ;
                    info.MeasurementValueString = info.MeasurementValue.ToString("F0");
                    break;
                case MeasurementKind.血红蛋白:
                    info.MeasurementValue = value * 0.1f;
                    info.MeasurementValueString = info.MeasurementValue.ToString("F1");
                    break;
                case MeasurementKind.总胆固醇:
                    info.MeasurementValue = value * 0.1f;
                    info.MeasurementValueString = info.MeasurementValue.ToString("F1");
                    break;
                default:
                    break;
            }

            var sampleLocation= bytes[byteIndex++];

            info.SampleType= (SampleType)((sampleLocation << 4) >> 4);
            info.SampleLocation = (SampleLocation)(sampleLocation>> 4);

            info.IsValid = true;

            return info;
        }

         
        private byte Flags { get; set; }

        /// <summary>
        /// 0 
        /// </summary>
        private bool TimeOffsetPresent { get; set; }

        /// <summary>
        /// 测量时间
        /// </summary>
        public DateTime MeasurementTime { get;  set; } = DateTime.Now;


        /// <summary>
        /// 时段的来源
        /// </summary>
        public BloodGlucosePeriodSourceKind BloodGlucosePeriodSourceKind { get; set; }

        /// <summary>
        /// 设置时段 同时结束
        /// </summary>
        /// <param name="bloodGlucosePeriod"></param>
        public void SetBloodGlucosePeriodThenComputeBloodGlucoseStatus(BloodGlucosePeriod bloodGlucosePeriod
            , BloodGlucosePeriodSourceKind bloodGlucosePeriodSourceKind= BloodGlucosePeriodSourceKind.Device)
        {
            BloodGlucosePeriod = bloodGlucosePeriod;
            this.BloodGlucosePeriodSourceKind= bloodGlucosePeriodSourceKind;
            ///重新计算 
            ComputeBloodGlucoseStatus();
        }

        /// <summary>
        /// 测量时段
        /// </summary>
        public BloodGlucosePeriod BloodGlucosePeriod { get; private set; } = BloodGlucosePeriod.Random;

        /// <summary>
        /// 血糖值
        /// </summary>
        public float MeasurementValue { get; set; } = 0;

        /// <summary>
        /// 血糖值
        /// </summary>
        public string MeasurementValueString {
            get;
            set;
        }
        /// <summary>
        /// 异常
        /// </summary>
        public bool IsUnusual
        {
            get; set;
        } = false;

        /// <summary>
        /// 血糖状态
        /// </summary>
        public BloodGlucoseStatus BloodGlucoseStatus { get; private set; }

        /// <summary>
        /// 
        /// </summary>
        private void ComputeBloodGlucoseStatus()
        {
            this.BloodGlucoseStatus = Extension.GetBloodGlucoseStatus(BloodGlucosePeriod, MeasurementValue);
            if (this.BloodGlucoseStatus== BloodGlucoseStatus.LO)
            {
                this.IsUnusual = true;
                this.MeasurementValueString = "LO";
            }
            if (this.BloodGlucoseStatus == BloodGlucoseStatus.HI)
            {
                this.IsUnusual = true;
                this.MeasurementValueString = "HI";
            }
        }
       
        /// <summary>
        /// 没有使用
        /// </summary>
        private bool LocationPresent { get; set; }
        /// <summary>
        /// 3
        /// </summary>
        private bool SensorStatusAnnunciationPresent { get; set; }
        /// <summary>
        /// 没有使用
        /// </summary>
        public bool ContextInformationFollows { get; private set; }
        /// <summary>
        /// 测量类型
        /// </summary>
        private MeasurementKind MeasurementKind { get; set; }
        /// <summary>
        /// 没有使用
        /// </summary>
        public int SeqNo { get; private set; }

        private short TimeOffset { get; set; }

        /// <summary>
        /// 
        /// </summary>
        private short GlucoseConcentration { get; set; }
        // public byte
        /// <summary>
        /// 
        /// </summary>
        private SampleType SampleType { get; set; }
        /// <summary>
        /// 
        /// </summary>
        private SampleLocation SampleLocation { get; set; }

        /// <summary>
        /// 
        /// </summary>
        private bool HasGlucoseConcentration { get; set; }



    }
}
